package com.kerbores.mongo.utils;

import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

import org.nutz.ioc.impl.PropertiesProxy;
import org.nutz.lang.Lang;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.Mvcs;

import com.mongodb.DB;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.MongoException;
import com.mongodb.ServerAddress;
import com.mongodb.WriteConcern;

/**
 * @author Kerbores<br>
 *
 *         create at 2014年11月13日 下午9:17:28
 */
public class MongoManager {

	private static PropertiesProxy mongoConfig;

	private static MongoClient client = null;

	private static DB db;

	protected static final Log LOG = Logs.get();

	static {
		try {
			mongoConfig = Mvcs.getIoc().get(PropertiesProxy.class, "mongoConfig");// 通过全局配置加载此对象
		} catch (Exception e) {
			LOG.error(" 'mongoConfig'  is not provided in ioc");
			System.err.println(" 'mongoConfig'  is not provided in ioc");
		}
		init();
	}

	private MongoManager() {
	}

	/**
	 * 根据名称获取DB，相当于是连接
	 * 
	 * @param dbName
	 *            database名称
	 * @return
	 */
	public static DB getDB(String dbName) {
		if (client == null) {
			init();
		}
		return client.getDB(dbName);
	}

	/**
	 * 通过配置信息获取db
	 * 
	 * @return
	 */
	public static DB getDb() {
		return db;
	}

	/**
	 * 获取mongoclient(此方法不暴露出去使用)
	 * 
	 * @return
	 */
	protected static MongoClient getClient() {
		return client;
	}

	/**
	 * 初始化连接池，设置参数。初始化配置信息和建立一个连接池
	 */
	private static void init() {
		// 从配置文件加载
		List<String> servers = Lang.array2list(mongoConfig.get("servers").split(","));
		List<ServerAddress> seeds = new ArrayList<ServerAddress>();
		for (String info : servers) {
			try {
				seeds.add(new ServerAddress(mongoConfig.get("server-" + info), mongoConfig.getInt("port-" + info, 27017)));
			} catch (UnknownHostException e) {
				LOG.error(e.getMessage(), e);
			}
		}
		int poolSize = mongoConfig.getInt("poolSize", 10); // 连接数量
		int blockSize = mongoConfig.getInt("waitingSize", 10);// 等待队列长度
		// 其他参数根据实际情况进行添加
		MongoClientOptions options = MongoClientOptions.builder().connectionsPerHost(poolSize).threadsAllowedToBlockForConnectionMultiplier(blockSize).build();
		
//		List<MongoCredential> credentials = Lang.list(MongoCredential.createMongoCRCredential(mongoConfig.get("user"), mongoConfig.get("dbName"), mongoConfig
//				.get("pwd").toCharArray()));// 认证信息列表
		try {
			client = new MongoClient(seeds, options);
			client.setWriteConcern(WriteConcern.SAFE);//至少有一个节点写成功
//			 client = new MongoClient(seeds, credentials, options);
		} catch (MongoException e) {
			LOG.error(e.getMessage(), e);
		}
		db = client.getDB(mongoConfig.get("dbName"));
	}
	
}
